| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for choosing the predicate global focus (that is, the “rule applied” or the “current shape”)
# File lib/interfaces/custom.rb, line 204
204: def create_GUI_dialog_focus(predicate_type, class_name)
205: gui_dialog_focus = UI::WebDialog.new("Choose #{predicate_type} focus", true, "Choose #{predicate_type} focus", 250, 150, 150, 150, true)
206:
207: # Attach an action callback for getting the chosen focus
208: gui_dialog_focus.add_action_callback("get_focus") do |web_dialog, focus|
209:
210: gui_dialog_focus.close
211:
212: if focus == "RULE APPLIED"
213: # Find and show our html file
214: html_path = Sketchup.find_support_file "GUIDialogRuleFocus.html" , Constants::HTML_DIR
215: gui_dialog_rule = create_GUI_dialog_rule(predicate_type, class_name)
216: gui_dialog_rule.set_file(html_path)
217: gui_dialog_rule.show()
218: elsif focus == "CURRENT SHAPE"
219: # Find and show our html file
220: html_path = Sketchup.find_support_file "GUIDialogShapeFocus.html" , Constants::HTML_DIR
221: gui_dialog_shape = create_GUI_dialog_shape(predicate_type, class_name)
222: gui_dialog_shape.set_file(html_path)
223: gui_dialog_shape.show()
224: end
225:
226: end
227:
228: return gui_dialog_focus
229: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the number of points of the shape
# File lib/interfaces/custom.rb, line 733
733: def create_GUI_dialog_number_of_points(predicate_type, class_name)
734: gui_dialog_number_of_points = UI::WebDialog.new("Configure points number #{predicate_type}", true, "Configure points number #{predicate_type}", 700, 100, 150, 150, true)
735:
736: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
737: gui_dialog_number_of_points.add_action_callback("get_data") do |web_dialog, data|
738:
739: gui_dialog_number_of_points.close
740: data_a = data.split(",")
741:
742: point_type = data_a[0]
743: relation_type = data_a[1]
744: argument_type = data_a[2]
745: number = data_a[3]
746: argument_point_type = data_a[4]
747:
748: code = "labels = ShadeUtils.get_labels(ShadeUtils.current_shape, \"#{point_type}\")
749: number = 0
750: labels.each { |list|
751: number += list.size
752: }"
753:
754: case argument_type
755: when "NUMBER"
756: code = "#{code}
757: argument_number = #{number}"
758: when "CURRENT SHAPE"
759: code = "#{code}
760: labels = ShadeUtils.get_labels(ShadeUtils.current_shape, \"#{argument_type }\")
761: argument_number = 0
762: labels.each { |list|
763: argument_number += list.size
764: }"
765: when "PREVIOUS SHAPE"
766: code = "#{code}
767: labels = ShadeUtils.get_labels(ShadeUtils.previous_shape, \"#{argument_type }\")
768: argument_number = 0
769: labels.each { |list|
770: argument_number += list.size
771: }"
772: end
773:
774: predicate_string = ""
775:
776: case relation_type
777: when "EQUAL"
778: predicate_string = "(number == argument_number)"
779: when "DIFFERENT"
780: predicate_string = "!(number == argument_number)"
781: when "BIGGER"
782: predicate_string = "(number > argument_number)"
783: when "LESS"
784: predicate_string = "(number < argument_number)"
785: when "BIGGEREQ"
786: predicate_string = "(number >= argument_number)"
787: when "LESSEQ"
788: predicate_string = "(number <= argument_number)"
789: end
790:
791: code = "#{code}
792: result = #{predicate_string}"
793:
794: create_code(predicate_type, class_name, code)
795: end
796:
797: return gui_dialog_number_of_points
798: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for choosing the points focus (that is, the “number of points” or the “position of points”)
# File lib/interfaces/custom.rb, line 316
316: def create_GUI_dialog_points_focus(predicate_type, class_name)
317: gui_dialog_points_focus = UI::WebDialog.new("Choose #{predicate_type} points focus", true, "Choose #{predicate_type} points focus", 250, 150, 150, 150, true)
318:
319: # Attach an action callback for getting the chosen points focus
320: gui_dialog_points_focus.add_action_callback("get_focus") do |web_dialog, focus|
321:
322: gui_dialog_points_focus.close
323:
324: if focus == "NUMBER OF POINTS"
325: # Find and show our html file
326: html_path = Sketchup.find_support_file "GUIDialogNumberOfPoints.html" ,Constants::HTML_DIR
327: gui_dialog_number_of_points = create_GUI_dialog_number_of_points(predicate_type, class_name)
328: gui_dialog_number_of_points.set_file(html_path)
329: gui_dialog_number_of_points.show()
330: elsif focus == "POSITION OF POINTS"
331: # Find and show our html file
332: html_path = Sketchup.find_support_file "GUIDialogPositionOfPoints.html" ,Constants::HTML_DIR
333: gui_dialog_position_of_points = create_GUI_dialog_position_of_points(predicate_type, class_name)
334: gui_dialog_position_of_points.set_file(html_path)
335: gui_dialog_position_of_points.show()
336: end
337:
338: end
339:
340: return gui_dialog_points_focus
341: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the position of the points of the current shape
# File lib/interfaces/custom.rb, line 806
806: def create_GUI_dialog_position_of_points(predicate_type, class_name)
807: gui_dialog_position_of_points = UI::WebDialog.new("Configure points position #{predicate_type}", true, "Configure points position #{predicate_type}", 700, 100, 150, 150, true)
808:
809: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
810: gui_dialog_position_of_points.add_action_callback("get_data") do |web_dialog, data|
811:
812: gui_dialog_position_of_points.close
813: data_a = data.split(",")
814:
815: quantification = data_a[0]
816: number = data_a[1]
817: point_type = data_a[2]
818: argument_point_type = data_a[3]
819: relation_type = data_a[4]
820: meters = data_a[5]
821:
822: code = "labels = ShadeUtils.get_labels(ShadeUtils.current_shape, \"#{point_type}\")"
823: if !(argument_point_type == "ORIGIN")
824: code = "#{code}
825: argument_labels = ShadeUtils.get_labels(ShadeUtils.current_shape, \"#{argument_point_type.capitalize}\")"
826: else
827: code = "#{code}
828: p = Point.new(0,0)"
829: end
830:
831: predicate_string = ""
832:
833: case relation_type
834: when "EQUAL"
835: predicate_string = "(l.key.point.distance(p) == #{meters}.m)"
836: when "DIFFERENT"
837: predicate_string = "!(l.key.point.distance(p) == #{meters}.m)"
838: when "BIGGER"
839: predicate_string = "(l.key.point.distance(p) > #{meters}.m)"
840: when "LESS"
841: predicate_string = "(l.key.point.distance(p) < #{meters}.m)"
842: when "BIGGEREQ"
843: predicate_string = "(l.key.point.distance(p) >= #{meters}.m)"
844: when "LESSEQ"
845: predicate_string = "(l.key.point.distance(p) <= #{meters}.m)"
846: end
847:
848: case quantification
849: when "ALL"
850: if !(argument_point_type == "ORIGIN")
851: code = "#{code}
852: ok = true
853: labels.each { |list|
854: list.reset_iterator
855: while l = list.get_next
856: found = false
857: i = 0
858: while ((i < argument_labels.size) && !found)
859: j = 0
860: while ((j < argument_labels[i].size) && !found)
861: if !(l==argument_labels[i].get_node_i(j))
862: p = argument_labels[i].get_node_i(j).key.point
863: if #{predicate_string}
864: found = true
865: end
866: end
867: j += 1
868: end
869: i += 1
870: end
871: ok = (ok && found)
872: end
873: }
874: result = ok"
875: else
876: code = "#{code}
877: ok = true
878: labels.each { |list|
879: list.reset_iterator
880: while l = list.get_next
881: if !#{predicate_string}
882: ok = false
883: end
884:
885: end
886: }
887: result = ok"
888: end
889: when "NUMBER"
890: if !(argument_point_type == "ORIGIN")
891: code = "#{code}
892: number = #{number}
893: number_l = 0
894: if labels.size > 0
895: labels.each { |list|
896: list.reset_iterator
897: while l = list.get_next
898: i = 0
899: while (i < argument_labels.size)
900: j = 0
901: found = false
902: while ((j < argument_labels[i].size) && !found)
903: if !(l==argument_labels[i].get_node_i(j))
904: p = argument_labels[i].get_node_i(j).key.point
905: if #{predicate_string}
906: number_l += 1
907: found = true
908: end
909: end
910: j += 1
911: end
912: i += 1
913: end
914: end
915: }
916: result = (number_l >= number)
917: end"
918:
919: else
920: code = "#{code}
921: number_l = 0
922: if labels.size > 0
923: labels.each { |list|
924: list.reset_iterator
925: while l = list.get_next
926: if !#{predicate_string}
927: number_l += 1
928: end
929: end
930: }
931: result = (number_l >= number)
932: end"
933: end
934:
935: end
936:
937: create_code(predicate_type, class_name, code)
938: end
939:
940: return gui_dialog_position_of_points
941: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for choosing the rule focus (that is, the “rule id” or the “rule transformation”)
# File lib/interfaces/custom.rb, line 237
237: def create_GUI_dialog_rule(predicate_type, class_name)
238: gui_dialog_rule = UI::WebDialog.new("Choose #{predicate_type} rule focus", true, "Choose #{predicate_type} rule focus", 250, 150, 150, 150, true)
239:
240: # Attach an action callback for getting the chosen focus
241: gui_dialog_rule.add_action_callback("get_focus") do |web_dialog, focus|
242:
243: gui_dialog_rule.close
244:
245: if focus == "RULE ID"
246: # Find and show our html file
247: html_path = Sketchup.find_support_file "GUIDialogRuleID.html" ,Constants::HTML_DIR
248: gui_rule_id = create_GUI_rule_id(predicate_type, class_name)
249: gui_rule_id.set_file(html_path)
250: gui_rule_id.show()
251: elsif focus == "FIRST RULE ID"
252: # Find and show our html file
253: html_path = Sketchup.find_support_file "GUIDialogFirstRuleID.html" ,Constants::HTML_DIR
254: gui_first_rule_id = create_GUI_first_rule_id(predicate_type, class_name)
255: gui_first_rule_id.set_file(html_path)
256: gui_first_rule_id.show()
257: elsif focus == "TRANSFORMATION"
258: # Find and show our html file
259: html_path = Sketchup.find_support_file "GUIDialogRuleTransformation.html" ,Constants::HTML_DIR
260: gui_rule_transformation = create_GUI_rule_transformation(predicate_type, class_name)
261: gui_rule_transformation.set_file(html_path)
262: gui_rule_transformation.show()
263: end
264:
265: end
266:
267: return gui_dialog_rule
268: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the segments of the current shape
# File lib/interfaces/custom.rb, line 949
949: def create_GUI_dialog_segments(predicate_type, class_name)
950: gui_dialog_segments = UI::WebDialog.new("Configure segments #{predicate_type}", true, "Configure segments #{predicate_type}", 700, 100, 150, 150, true)
951:
952: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
953: gui_dialog_segments.add_action_callback("get_data") do |web_dialog, data|
954:
955: gui_dialog_segments.close
956: data_a = data.split(",")
957:
958: quantification = data_a[0]
959: number = data_a[1]
960: relation_type = data_a[2]
961: meters = data_a[3]
962:
963: predicate_string = ""
964: case relation_type
965: when "EQUAL"
966: predicate_string = "(s.key.length == #{meters}.m)"
967: when "DIFFERENT"
968: predicate_string = "!(s.key.length == #{meters}.m)"
969: when "BIGGER"
970: predicate_string = "(s.key.length > #{meters}.m)"
971: when "LESS"
972: predicate_string = "(s.key.length < #{meters}.m)"
973: when "BIGGEREQ"
974: predicate_string = "(s.key.length >= #{meters}.m)"
975: when "LESSEQ"
976: predicate_string = "(s.key.length <= #{meters}.m)"
977: end
978:
979: code = ""
980:
981: case quantification
982: when "ALL"
983: code = "ok = true
984: ShadeUtils.current_shape.s.each_key { |layer_name|
985: ShadeUtils.current_shape.s[layer_name].reset_iterator
986: while s_node = ShadeUtils.current_shape.s[layer_name].get_next
987: s_node.list.reset_iterator
988: while s = s_node.list.get_next
989: if !#{predicate_string}
990: ok = false
991: end
992: end
993: end
994: }
995: result = ok"
996: when "NUMBER"
997: code = "number_s = 0
998: number = #{number}
999: ShadeUtils.current_shape.s.each_key { |layer_name|
1000: ShadeUtils.current_shape.s[layer_name].reset_iterator
1001: while s_node = ShadeUtils.current_shape.s[layer_name].get_next
1002: s_node.list.reset_iterator
1003: while s = s_node.list.get_next
1004: if #{predicate_string}
1005: number_s += 1
1006: end
1007: end
1008: end
1009: }
1010: result = (number_s >= number)"
1011:
1012: end
1013:
1014: create_code(predicate_type, class_name, code)
1015: end
1016:
1017: return gui_dialog_segments
1018:
1019: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for choosing the current shape focus (that is, the “whole shape”, the “points” or the “segments”)
# File lib/interfaces/custom.rb, line 277
277: def create_GUI_dialog_shape(predicate_type, class_name)
278: gui_dialog_shape = UI::WebDialog.new("Choose #{predicate_type} shape focus", true, "Choose #{predicate_type} shape focus", 250, 150, 150, 150, true)
279:
280: # Attach an action callback for getting the chosen current shape focus
281: gui_dialog_shape.add_action_callback("get_focus") do |web_dialog, focus|
282:
283: gui_dialog_shape.close
284:
285: if focus == "WHOLE SHAPE"
286: # Find and show our html file
287: html_path = Sketchup.find_support_file "GUIDialogWholeShape.html" ,Constants::HTML_DIR
288: gui_dialog_whole_shape = create_GUI_dialog_whole_shape(predicate_type, class_name)
289: gui_dialog_whole_shape.set_file(html_path)
290: gui_dialog_whole_shape.show()
291: elsif focus == "POINTS"
292: # Find and show our html file
293: html_path = Sketchup.find_support_file "GUIDialogPointsFocus.html" ,Constants::HTML_DIR
294: gui_dialog_points_focus = create_GUI_dialog_points_focus(predicate_type, class_name)
295: gui_dialog_points_focus.set_file(html_path)
296: gui_dialog_points_focus.show()
297: elsif focus == "SEGMENTS"
298: # Find and show our html file
299: html_path = Sketchup.find_support_file "GUIDialogSegments.html" ,Constants::HTML_DIR
300: gui_dialog_segments_focus = create_GUI_dialog_segments(predicate_type, class_name)
301: gui_dialog_segments_focus.set_file(html_path)
302: gui_dialog_segments_focus.show()
303: end
304:
305: end
306:
307: return gui_dialog_shape
308: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the whole shape
# File lib/interfaces/custom.rb, line 594
594: def create_GUI_dialog_whole_shape(predicate_type, class_name)
595: gui_dialog_whole_shape = UI::WebDialog.new("Configure whole shape #{predicate_type}", true, "Configure whole shape #{predicate_type}", 700, 100, 150, 150, true)
596:
597: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
598: gui_dialog_whole_shape.add_action_callback("get_data") do |web_dialog, data|
599:
600: data_a = data.split(",")
601: ok = true
602:
603: relation_type = data_a[0]
604: shape = data_a[1]
605:
606: code = ""
607:
608: ok = true
609: case shape
610: when "AXIOM"
611: code = "shape = ShadeUtils.axiom"
612: when "PREVIOUS SHAPE"
613: code = "shape = ShadeUtils.previous_shape"
614: when "FILE SHAPE"
615: load_shape_path = UI.openpanel "Load Shape", "", "*.txt"
616: code = "shape = LabelledShape.new([], [])
617: shape.load(#{load_shape_path})"
618: when "FILE CONTOUR"
619: chosen_area_path = UI.openpanel("Open area", "" ,"*.area")
620: if chosen_area_path
621: points_string = nil
622: File.open(chosen_area_path, 'r') do |f|
623: while line = f.gets
624: line_a = line.split
625: point = Array.new
626: point[0] = line_a[0].to_f.m
627: point[1] = line_a[1].to_f.m
628: point[2] = line_a[2].to_f.m
629: if points_string
630: points_string = "#{points_string},[#{point[0]}, #{point[1]}, #{point[2]}]"
631: else
632: points_string = "[[#{point[0]}, #{point[1]}, #{point[2]}]"
633: end
634: end
635: points_string = "#{points_string}]"
636: end
637: code = "#{code}
638: shape = true
639: ac = AreaConstraint.new(#{points_string})"
640: else
641: ok = false
642: end
643: end
644:
645: if ok
646: predicate_string = ""
647:
648: case relation_type
649: when "EQUAL"
650: if (shape == "FILE CONTOUR")
651: ok = false
652: UI.messagebox("You cannot use file contour option with equal relation")
653: else
654: predicate_string = "(ShadeUtils.current_shape == shape)"
655: end
656: when "DIFFERENT"
657: if (shape == "FILE CONTOUR")
658: ok = false
659: UI.messagebox("You cannot use file contour option with different relation")
660: else
661: predicate_string = "!(ShadeUtils.current_shape == shape)"
662: end
663: when "SUBSHAPE"
664: if (shape == "FILE CONTOUR")
665: ok = false
666: UI.messagebox("You cannot use file contour option with subshape relation")
667: else
668: code = "#{code}
669: flag_s= shape.shape_expression(ShadeUtils.current_shape, Constants::SUBSHAPE, Constants::SEGMENTS, false)
670: flag_p = shape.shape_expression(ShadeUtils.current_shape, Constants::SUBSHAPE, Constants::POINTS, false)"
671: predicate_string = "(flag_s && flag_p)"
672: end
673: when "SUPERSHAPE"
674: if (shape == "FILE CONTOUR")
675: ok = false
676: UI.messagebox("You cannot use file contour option with supershape relation")
677: else
678: code = "#{code}
679: flag_s= ShadeUtils.current_shape.shape_expression(shape, Constants::SUBSHAPE, Constants::SEGMENTS, false)
680: flag_p = ShadeUtils.current_shape.shape_expression(shape, Constants::SUBSHAPE, Constants::POINTS, false)"
681: predicate_string = "(flag_s && flag_p)"
682: end
683: when "NOT SUBSHAPE"
684: if (shape == "FILE CONTOUR")
685: ok = false
686: UI.messagebox("You cannot use file contour option with subshape relation")
687: else
688: code = "#{code}
689: flag_s= shape.shape_expression(ShadeUtils.current_shape, Constants::SUBSHAPE, Constants::SEGMENTS, false)
690: flag_p = shape.shape_expression(ShadeUtils.current_shape, Constants::SUBSHAPE, Constants::POINTS, false)"
691: predicate_string = "!(flag_s && flag_p)"
692: end
693: when "NOT SUPERSHAPE"
694: if (shape == "FILE CONTOUR")
695: ok = false
696: UI.messagebox("You cannot use file contour option with supershape relation")
697: else
698: code = "#{code}
699: flag_s= ShadeUtils.current_shape.shape_expression(shape, Constants::SUBSHAPE, Constants::SEGMENTS, false)
700: flag_p = ShadeUtils.current_shape.shape_expression(shape, Constants::SUBSHAPE, Constants::POINTS, false)"
701: predicate_string = "!(flag_s && flag_p)"
702: end
703: when "INSIDE"
704: if !(shape == "FILE CONTOUR")
705: ok = false
706: UI.messagebox("You have to specify the file contour option")
707: end
708: predicate_string = "ac.satisfied?"
709: end
710: end
711:
712: if ok
713: gui_dialog_whole_shape.close
714:
715: code = "#{code}
716: result = true
717: if shape
718: result = #{predicate_string}
719: end"
720: create_code(predicate_type, class_name, code)
721: end
722: end
723:
724: return gui_dialog_whole_shape
725: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the first applied rule id
# File lib/interfaces/custom.rb, line 472
472: def create_GUI_first_rule_id(predicate_type, class_name)
473: gui_dialog_first_rule_id = UI::WebDialog.new("Configure first rule id #{predicate_type}", true, "Configure first rule id #{predicate_type}", 700, 100, 150, 150, true)
474:
475: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
476: gui_dialog_first_rule_id.add_action_callback("get_data") do |web_dialog, data|
477:
478: gui_dialog_first_rule_id.close
479: data_a = data.split(",")
480:
481: relation_type = data_a[0]
482: number = data_a[1]
483:
484: predicate_string = ""
485:
486: case relation_type
487: when "EQUAL"
488: predicate_string = "(ShadeUtils.first_rule_id == #{number}"
489: when "DIFFERENT"
490: predicate_string = "!(ShadeUtils.first_rule_id == #{number}"
491: when "BIGGER"
492: predicate_string = "(ShadeUtils.first_rule_id > #{number}"
493: when "LESS"
494: predicate_string = "(ShadeUtils.first_rule_id < #{number}"
495: when "BIGGEREQ"
496: predicate_string = "(ShadeUtils.first_rule_id >= #{number}"
497: when "LESSEQ"
498: predicate_string = "(ShadeUtils.first_rule_id <= #{number}"
499: end
500:
501:
502: code = "if Shade.project.execution.execution_history
503: if Shade.project.execution.execution_history.size == 1
504: result = #{predicate_string})
505: end
506: end"
507:
508:
509: create_code(predicate_type, class_name, code)
510: end
511:
512: return gui_dialog_first_rule_id
513: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the applied rule id
# File lib/interfaces/custom.rb, line 410
410: def create_GUI_rule_id(predicate_type, class_name)
411: gui_dialog_rule_id = UI::WebDialog.new("Configure rule id #{predicate_type}", true, "Configure rule id #{predicate_type}", 700, 100, 150, 150, true)
412:
413: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
414: gui_dialog_rule_id.add_action_callback("get_data") do |web_dialog, data|
415:
416: gui_dialog_rule_id.close
417: data_a = data.split(",")
418:
419: relation_type = data_a[0]
420: id_type = data_a[1]
421: number = data_a[2]
422:
423: predicate_string = ""
424:
425: case relation_type
426: when "EQUAL"
427: predicate_string = "(ShadeUtils.last_rule_id =="
428: when "DIFFERENT"
429: predicate_string = "!(ShadeUtils.last_rule_id =="
430: when "BIGGER"
431: predicate_string = "(ShadeUtils.last_rule_id >"
432: when "LESS"
433: predicate_string = "(ShadeUtils.last_rule_id <"
434: when "BIGGEREQ"
435: predicate_string = "(ShadeUtils.last_rule_id >="
436: when "LESSEQ"
437: predicate_string = "(ShadeUtils.last_rule_id <="
438: when "FOLLOWING"
439: predicate_string = "(ShadeUtils.last_rule_id - 1 =="
440: end
441:
442: code = ""
443:
444: case id_type
445: when "PREVIOUS"
446: predicate_string = "#{predicate_string} ShadeUtils.previous_rule_id"
447: code = "if Shade.project.execution.execution_history
448: if Shade.project.execution.execution_history.size > 1
449: result = #{predicate_string})
450: end
451: end"
452: when "NUMBER"
453: predicate_string = "#{predicate_string} #{number}"
454: code = "if Shade.project.execution.execution_history
455: result = #{predicate_string})
456: end"
457: end
458:
459:
460: create_code(predicate_type, class_name, code)
461: end
462:
463: return gui_dialog_rule_id
464: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the applied rule transformation
# File lib/interfaces/custom.rb, line 521
521: def create_GUI_rule_transformation(predicate_type, class_name)
522: gui_dialog_rule_transformation = UI::WebDialog.new("Configure rule transformation #{predicate_type}", true, "Configure rule transformation #{predicate_type}", 700, 100, 150, 150, true)
523:
524: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
525: gui_dialog_rule_transformation.add_action_callback("get_data") do |web_dialog, data|
526:
527: gui_dialog_rule_transformation.close
528: data_a = data.split(",")
529:
530: transformation_type = data_a[0]
531: relation_type = data_a[1]
532: number = data_a[2]
533:
534: code = ""
535:
536: case transformation_type
537: when "XTRASLATION"
538: code = "last_t = ShadeUtils.last_rule_transformation()
539: factor = last_t[2]"
540: when "YTRASLATION"
541: code = "last_t = ShadeUtils.last_rule_transformation()
542: factor = last_t[5]"
543: when "ROTATION"
544: code = "last_t = ShadeUtils.last_rule_transformation()
545: if !(last_t[5] == 0)
546: factor = Math.atan(last_t[4].quo(last_t[5]))
547: elsif !(last_t[0] == 0)
548: factor = Math.atan(-1*(last_t[1].quo(last_t[0])))
549: elsif (last_t[4] > 0)
550: factor = Math::PI / 2
551: else
552: factor = -1*(Math::PI / 2)
553: end"
554:
555: when "SCALE"
556: code = "last_t = ShadeUtils.last_rule_transformation()
557: factor = Math.sqrt(last_t[0]**2 + last_t[1]**2)"
558: end
559:
560: predicate_string = ""
561:
562: case relation_type
563: when "EQUAL"
564: predicate_string = "(factor == #{number})"
565: when "DIFFERENT"
566: predicate_string = "!(factor == #{number})"
567: when "BIGGER"
568: predicate_string = "(factor > #{number})"
569: when "LESS"
570: predicate_string = "(factor < #{number})"
571: when "BIGGEREQ"
572: predicate_string = "(factor >= #{number})"
573: when "LESSEQ"
574: predicate_string = "(factor <= #{number})"
575: end
576:
577: code = "#{code}
578: if Shade.project.execution.execution_history
579: result = #{predicate_string}
580: end"
581:
582: create_code(predicate_type, class_name, code)
583: end
584:
585: return gui_dialog_rule_transformation
586: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for choosing the type of interface to be used when creating a custom constraint or goal
# File lib/interfaces/custom.rb, line 49
49: def create_choose_interface_dialog(predicate_type, class_name)
50: # Create the WebDialog instance for choosing the interface type
51: choose_interface_dialog = UI::WebDialog.new("Choose interface type", true, "Choose interface type", 250, 150, 150, 150, true)
52:
53: # Attach an action callback
54: choose_interface_dialog.add_action_callback("get_type") do |web_dialog, type|
55:
56: choose_interface_dialog.close
57:
58: if type == "GUI"
59: # Find and show our html file
60: html_path = Sketchup.find_support_file "GUIDialogFocus.html" , Constants::HTML_DIR
61: gui_dialog_focus = create_GUI_dialog_focus(predicate_type, class_name)
62: gui_dialog_focus.set_file(html_path)
63: gui_dialog_focus.show()
64: elsif type == "CODE"
65: # Find and show our html file
66: html_path = Sketchup.find_support_file "write#{predicate_type}CustomCode.html" , Constants::HTML_DIR
67: code_dialog = create_code_dialog(predicate_type, class_name)
68: code_dialog.set_file(html_path)
69: code_dialog.show()
70: end
71:
72: end
73:
74: return choose_interface_dialog
75: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
| code | string with the code for the method “satisfied” of either a constraint or a goal |
Method that creates the class and stores the code for a custom constraint or goal
# File lib/interfaces/custom.rb, line 350
350: def create_code(predicate_type, class_name, code)
351: # Create the class
352: bad_sintax = false
353: begin
354: #Define the class without satisfied? method (if the name is properly chosen, then the next eval clause will not raise errors)
355: Object.const_set(class_name, Class.new {
356:
357: eval("attr_reader :name")
358:
359: eval("def initialize; @name = \"#{class_name}\" end")
360:
361: eval("def delete; end")
362:
363: })
364:
365: code = "#{code}
366: return result"
367: # Define (or re-define) the satisfied? method
368: eval("class #{class_name}
369:
370: def satisfied?; result = true\n #{code}\n end
371:
372: end")
373: rescue Exception => e
374: bad_syntax = true
375: string_errors = e.message.gsub("\n", " ").gsub("\t", " ").gsub(":in `create_execution_toolbar'", "")
376: end
377:
378: if !bad_sintax
379: # Write the code into an auxiliar file
380: file_name = Sketchup.find_support_file Constants::STARTUP_FILE_NAME, Constants::LIB_DIR
381: directory = ShadeUtils.get_directory_from_sketchup_path(file_name)
382: if predicate_type == "Constraint"
383: File.open("#{directory}//#{Constants::CONSTRAINT_FOLDER_NAME}//#{class_name}.txt", 'w') do |f|
384: f.write ("#{code}\n")
385: end
386: # Add the constraint to the project
387: constraint_class = eval("#{class_name}")
388: constraint = constraint_class.new
389: Shade.project.execution.add_constraint(constraint)
390: Shade.add_constraint_class_name([constraint_class, class_name])
391: else
392: File.open("#{directory}//#{Constants::GOAL_FOLDER_NAME}//#{class_name}.txt", 'w') do |f|
393: f.write ("#{code}\n")
394: end
395: # Add the goal to the project
396: goal_class = eval("#{class_name}")
397: goal = goal_class.new
398: Shade.project.execution.add_goal(goal)
399: Shade.add_goal_class_name([goal_class, class_name])
400: end
401: end
402: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
| class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for directly typing the code of a custom constraint or goal
# File lib/interfaces/custom.rb, line 83
83: def create_code_dialog(predicate_type, class_name)
84: code = nil
85: # Create the WebDialog instance for writing the code
86: code_dialog = UI::WebDialog.new("Write #{predicate_type} custom code", true, "Write #{predicate_type} custom code", 550, 750, 150, 150, true)
87:
88: # Attach an action callback for checking the code syntax
89: code_dialog.add_action_callback("check_syntax") do |web_dialog, code|
90: # Fix the code
91: code.gsub!("<BR>", "\n")
92: code.gsub!("<TAB>", "\t")
93:
94: # Eval the method rescuing the exceptions
95: string_errors = ""
96: begin
97:
98: #Define the class without satisfied? method (if the name is properly chosen, then the next eval clause will not raise errors)
99: Object.const_set(class_name, Class.new {
100:
101: eval("attr_reader :name")
102:
103: eval("def initialize; @name = \"#{class_name}\" end")
104:
105: eval("def delete; end")
106:
107: })
108:
109: code = "#{code}
110: return result"
111:
112: # Define (or re-define) the satisfied? method
113: eval("class #{class_name}
114:
115: def satisfied?; result = true\n #{code}\n end
116:
117: end")
118: rescue Exception => e
119: bad_syntax = true
120: string_errors = e.message.gsub("\n", " ").gsub("\t", " ").gsub(":in `create_execution_toolbar'", "")
121: end
122:
123: js_command = ""
124: if bad_syntax
125: js_command = "writeSyntaxResults(\"#{string_errors}\")"
126: else
127: js_command = "writeSyntaxResults(\"Syntax OK\")"
128: end
129: web_dialog.execute_script(js_command)
130: end
131:
132: # Attach an action callback for executing the code
133: code_dialog.add_action_callback("execute_code") do |web_dialog, rubish_code|
134: # Execute the method satisfied? rescuing the exceptions
135: # If we are here, it means the method satisfied? has been created
136: string_errors = ""
137: if predicate_type == "Constraint"
138: begin
139: constraint_class = eval("#{class_name}")
140: constraint = constraint_class.new
141: constraint.satisfied?
142: rescue Exception => e
143: bad_execution = true
144: string_errors = e.message.gsub("\n", " ").gsub("\t", " ")
145: end
146: else
147: begin
148: goal_class = eval("#{class_name}")
149: goal = goal_class.new
150: goal.satisfied?
151: rescue Exception => e
152: bad_execution = true
153: string_errors = e.message.gsub("\n", " ").gsub("\t", " ")
154: end
155: end
156:
157: js_command = ""
158: if bad_execution
159: js_command = "writeExecutionResults(\"#{string_errors}\")"
160: else
161: js_command = "writeExecutionResults(\"Execution OK\")"
162: end
163: web_dialog.execute_script(js_command)
164: end
165:
166: # Attach an action callback for saving the code
167: code_dialog.add_action_callback("write_code") do |web_dialog, rubish_code|
168: # Write the code into an auxiliar file
169: file_name = Sketchup.find_support_file Constants::STARTUP_FILE_NAME, Constants::LIB_DIR
170: directory = ShadeUtils.get_directory_from_sketchup_path(file_name)
171: if predicate_type == "Constraint"
172: File.open("#{directory}//#{Constants::CONSTRAINT_FOLDER_NAME}//#{class_name}.txt", 'w') do |f|
173: f.write ("#{code}\n")
174: end
175: # Add the constraint to the project
176: constraint_class = eval("#{class_name}")
177: constraint = constraint_class.new
178: Shade.project.execution.add_constraint(constraint)
179: Shade.add_constraint_class_name([constraint_class, class_name])
180: else
181: File.open("#{directory}//#{Constants::GOAL_FOLDER_NAME}//#{class_name}.txt", 'w') do |f|
182: f.write ("#{code}\n")
183: end
184: # Add the goal to the project
185: goal_class = eval("#{class_name}")
186: goal = goal_class.new
187: Shade.project.execution.add_goal(goal)
188: Shade.add_goal_class_name([goal_class, class_name])
189: end
190:
191: # Close the code dialog
192: code_dialog.close
193: end
194:
195: return code_dialog
196: end
Method that creates the toolbar for performing execution tasks
# File lib/interfaces/guitools.rb, line 896
896: def create_execution_toolbar()
897:
898: toolbar = UI.toolbar Constants::EXECUTION_TOOLBAR_NAME
899:
900: # Load Axiom command
901: load_axiom_cmd = UI::Command.new("load_axiom"){
902: Sketchup.active_model.close_active
903:
904: opened = false
905: while !opened
906: chosen_axiom_path = UI.openpanel("Load axiom", "" ,"*.txt")
907: if chosen_axiom_path
908: if ShadeUtils.get_extension(chosen_axiom_path) == "txt"
909: begin
910: new_axiom = LabelledShape.new(Array.new, Array.new)
911: new_axiom.load(chosen_axiom_path)
912: Shade.project.execution.file_axiom = true
913: Shade.project.execution.grammar.axiom = new_axiom
914: Shade.project.execution.reset
915: opened = true
916: rescue LoadError => e
917: UI.messagebox(e.message)
918: rescue
919: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)")
920: end
921: else
922: UI.messagebox("Please choose a .txt file")
923: end
924: else
925: opened = true
926: end
927: end
928: }
929: load_axiom_cmd.tooltip = "Load Axiom"
930: load_axiom_cmd.small_icon = File.join(Constants::ICONS_DIR, "load_axiom.PNG")
931: load_axiom_cmd.large_icon = File.join(Constants::ICONS_DIR, "load_axiom.PNG")
932: toolbar.add_item load_axiom_cmd
933:
934: # First-Rule Axiom command
935: first_rule_axiom_cmd = UI::Command.new("first_rule_axiom"){
936: execution = Shade.project.execution
937: execution.file_axiom = false
938: rule = execution.grammar.rules[0]
939: # Add new axiom
940: new_axiom = LabelledShape.new(Array.new, Array.new)
941: Sketchup.active_model.layers.each { |layer|
942: new_axiom.p[layer.name] = rule.left.p[layer.name].clone
943: new_axiom.s[layer.name] = rule.left.s[layer.name].clone
944: }
945: execution.grammar.axiom = new_axiom
946:
947: execution.reset
948: }
949: first_rule_axiom_cmd.tooltip = "Set the axiom to the first-rule-left shape"
950: first_rule_axiom_cmd.small_icon = File.join(Constants::ICONS_DIR, "first_rule_axiom.PNG")
951: first_rule_axiom_cmd.large_icon = File.join(Constants::ICONS_DIR, "first_rule_axiom.PNG")
952: toolbar.add_item first_rule_axiom_cmd
953:
954: toolbar.add_separator
955:
956: # Execute command
957: exe_cmd = UI::Command.new("apply_rule"){
958: project = Shade.project
959: execution = Shade.project.execution
960: Sketchup.active_model.close_active
961:
962: prompts = ["Chosen rule id"]
963: default = [1]
964: rule_list = ShadeUtils.create_rule_list()
965: list = [rule_list]
966: input = UI.inputbox prompts, default, list, "Apply Rule"
967: if input
968: chosen_rule_idx = input[0]
969: chosen_rule_id = execution.grammar.rules[chosen_rule_idx.to_i - 1].rule_id
970:
971: #STEP 1: Save temp files
972: save_temp_files()
973:
974: #STEP 2: Call external command with argument: chosen_rule_id
975: command_directory = "#{File.dirname(__FILE__)}/#{Constants::COMMANDS_DIR}/execute-command.rb"
976: command_directory.gsub!("/", "\\")
977: output = system("ruby \"#{command_directory}\" #{chosen_rule_id}")
978:
979: #STEP 3: Catch return from external command
980: if !($? == 0)
981: UI.messagebox("The loaded constraints/goals use some functions of SketchUp API. The execution will be performed inside the SketchUp environment, and it may take more time.")
982: #puts output
983: success = execution.apply_rule(chosen_rule_id)
984: if !success
985: UI.messagebox("The rule cannot be applied")
986: end
987: else
988: log_directory = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/result.log"
989: log_directory.gsub!("/", "\\")
990: File.open(log_directory, 'r') do |f|
991: line = f.gets.strip
992: if (line == "true")
993: load_temp_files()
994: elsif (line == "false")
995: UI.messagebox("The rule cannot be applied")
996: end
997: end
998: end
999:
1000: #STEP 4: delete files of temporal directory
1001: delete_temp_files()
1002: end
1003: }
1004: exe_cmd.tooltip = "Apply rule"
1005: exe_cmd.small_icon = File.join(Constants::ICONS_DIR, "execute.PNG")
1006: exe_cmd.large_icon = File.join(Constants::ICONS_DIR, "execute.PNG")
1007: toolbar.add_item exe_cmd
1008:
1009: # Ramdom Execute command
1010: rand_exe_cmd = UI::Command.new("apply_random_rule"){
1011: project = Shade.project
1012: execution = Shade.project.execution
1013: Sketchup.active_model.close_active
1014:
1015: #STEP 1: Save temp files
1016: save_temp_files()
1017:
1018: #STEP 2: Call external command with argument: chosen_rule_id
1019: command_directory = "#{File.dirname(__FILE__)}/#{Constants::COMMANDS_DIR}/execute-random-command.rb"
1020: command_directory.gsub!("/", "\\")
1021: system("ruby \"#{command_directory}\"")
1022:
1023: #STEP 3: Catch return from external command
1024: if !($? == 0)
1025: UI.messagebox("The loaded constraints/goals use some functions of SketchUp API. The execution will be performed inside the SketchUp environment, and it may take more time.")
1026: success = execution.apply_rule_random()
1027: if !success
1028: UI.messagebox("No rule can be applied")
1029: end
1030: else
1031: log_directory = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/result.log"
1032: log_directory.gsub!("/", "\\")
1033: File.open(log_directory, 'r') do |f|
1034: line = f.gets.strip
1035: if (line == "true")
1036: load_temp_files()
1037: elsif (line == "false")
1038: UI.messagebox("No rule can be applied")
1039: end
1040: end
1041: end
1042:
1043: #STEP 4: delete files of temporal directory
1044: delete_temp_files()
1045: }
1046: rand_exe_cmd.tooltip = "Apply random rule"
1047: rand_exe_cmd.small_icon = File.join(Constants::ICONS_DIR, "execute_random.PNG")
1048: rand_exe_cmd.large_icon = File.join(Constants::ICONS_DIR, "execute_random.PNG")
1049: toolbar.add_item rand_exe_cmd
1050:
1051: # Random n-execute command
1052: rand_n_exe_cmd = UI::Command.new("apply_n_random_rules"){
1053: project = Shade.project
1054: execution = Shade.project.execution
1055: Sketchup.active_model.close_active
1056:
1057: prompts = ["Number of rules", "See steps?"]
1058: default = ["0", "No"]
1059: list = ["", "No|Yes"]
1060: input = UI.inputbox prompts, default, list, "Apply n random rules"
1061: if input
1062: show_backtracking_steps = false
1063: if input[1] == "Yes"
1064: show_backtracking_steps = true
1065: end
1066: if show_backtracking_steps
1067: n_applied = execution.apply_n_rules_random(input[0].to_i, show_backtracking_steps)
1068: if n_applied
1069: UI.messagebox("Success. Number of steps: "+execution.backtracking_steps.to_s)
1070: else
1071: UI.messagebox("Failure. Impossible to apply " + input[0] + " rules.")
1072: end
1073: else #Try external execution
1074: #STEP 1: Save temp files
1075: save_temp_files()
1076:
1077: #STEP 2: Call external command with argument: chosen_rule_id
1078: command_directory = "#{File.dirname(__FILE__)}/#{Constants::COMMANDS_DIR}/n-execute-random-command.rb"
1079: command_directory.gsub!("/", "\\")
1080: system("ruby \"#{command_directory}\" #{input[0].to_i}")
1081:
1082: #STEP 3: Catch return from external command
1083: if !($? == 0)
1084: UI.messagebox("The loaded constraints/goals use some functions of SketchUp API. The execution will be performed inside the SketchUp environment, and it may take more time.")
1085: success = execution.apply_n_rules_random(input[0].to_i, false)
1086: if !success
1087: UI.messagebox("The rule cannot be applied")
1088: end
1089: else
1090: log_directory = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/result.log"
1091: log_directory.gsub!("/", "\\")
1092: File.open(log_directory, 'r') do |f|
1093: line = f.gets.strip
1094: if (line == "false")
1095: UI.messagebox("Failure. Impossible to apply #{input[0]} rules.")
1096: else
1097: load_temp_files()
1098: UI.messagebox("Success. Number of steps: #{line}")
1099: end
1100: end
1101: end
1102:
1103: #STEP 4: delete files of temporal directory
1104: delete_temp_files()
1105: end
1106: end
1107: }
1108: rand_n_exe_cmd.tooltip = "Apply n random rules"
1109: rand_n_exe_cmd.small_icon = File.join(Constants::ICONS_DIR, "execute_n_random.PNG")
1110: rand_n_exe_cmd.large_icon = File.join(Constants::ICONS_DIR, "execute_n_random.PNG")
1111: toolbar.add_item rand_n_exe_cmd
1112:
1113: # Random goal-execute command
1114: rand_goal_exe_cmd = UI::Command.new("apply_goal_random_rules"){
1115: project = Shade.project
1116: execution = Shade.project.execution
1117: Sketchup.active_model.close_active
1118:
1119: if !execution.goals.empty?
1120:
1121: prompts = ["See steps?", "Timeout (secs)?", "Maximum number of rules?"]
1122: default = ["No", "No timeout", "100"]
1123: list = ["No|Yes", "15|30|60|No timeout", ""]
1124: input = UI.inputbox prompts, default, list, "Apply random rules until goals are achieved"
1125:
1126: if input
1127: show_backtracking_steps = false
1128: if input[0] == "Yes"
1129: show_backtracking_steps = true
1130: end
1131: timeout = 0
1132: if input[1] != "No timeout"
1133: timeout = input[2].to_i
1134: end
1135: if input[2] != "No maximum"
1136: n_max_rules = input[2].to_i
1137: end
1138:
1139: if show_backtracking_steps
1140: t1 = Time.now
1141: n_applied = execution.apply_goal_rules_random(show_backtracking_steps, timeout, n_max_rules)
1142: t2 = Time.now
1143: if n_applied
1144: UI.messagebox("Success. Number of steps: "+execution.backtracking_steps.to_s)
1145: else
1146: UI.messagebox("Failure. Impossible to comply the goals")
1147: end
1148: puts "Elapsed time: #{t2 - t1}"
1149: else
1150: #STEP 1: Save temp files
1151: save_temp_files()
1152:
1153: #STEP 2: Call external command with argument: chosen_rule_id
1154: command_directory = "#{File.dirname(__FILE__)}/#{Constants::COMMANDS_DIR}/random-goal-execute-command.rb"
1155: command_directory.gsub!("/", "\\")
1156: t1 = Time.now
1157: system("ruby \"#{command_directory}\" #{timeout} #{n_max_rules}")
1158: t2 = Time.now
1159:
1160: #STEP 3: Catch return from external command
1161: if !($? == 0)
1162: UI.messagebox("The loaded constraints/goals use some functions of SketchUp API. The execution will be performed inside the SketchUp environment, and it may take more time.")
1163: t1 = Time.now
1164: n_applied = execution.apply_goal_rules_random(show_backtracking_steps, timeout, n_max_rules)
1165: t2 = Time.now
1166: puts "Elapsed time: #{t2 - t1}"
1167: if n_applied == 1
1168: UI.messagebox("No goals are speficied")
1169: elsif n_applied
1170: UI.messagebox("Success. Number of steps: #{execution.backtracking_steps.to_s}")
1171: else
1172: UI.messagebox("Failure. Impossible to satisfy the specified goals")
1173: end
1174: else
1175: log_directory = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/result.log"
1176: log_directory.gsub!("/", "\\")
1177: File.open(log_directory, 'r') do |f|
1178: line = f.gets
1179: if (line == "false")
1180: UI.messagebox("Failure. Impossible to satisfy the specified goals")
1181: else
1182: load_temp_files()
1183: UI.messagebox("Success. Number of steps: #{line}")
1184: puts "Elapsed time: #{t2 - t1}"
1185: end
1186: end
1187: end
1188:
1189: #STEP 4: delete files of temporal directory
1190: delete_temp_files()
1191: end
1192: end
1193: else
1194: UI.messagebox("No goals are speficied")
1195: end
1196:
1197: }
1198: rand_goal_exe_cmd.tooltip = "Apply random rules until goals are achieved"
1199: rand_goal_exe_cmd.small_icon = File.join(Constants::ICONS_DIR, "execute_goal_random.PNG")
1200: rand_goal_exe_cmd.large_icon = File.join(Constants::ICONS_DIR, "execute_goal_random.PNG")
1201: toolbar.add_item rand_goal_exe_cmd
1202:
1203: # Undo step command
1204: undo_step_cmd = UI::Command.new("undo_step"){
1205: project = Shade.project
1206: execution = Shade.project.execution
1207: Sketchup.active_model.close_active
1208:
1209: execution.undo
1210: }
1211: undo_step_cmd.tooltip = "Undo Step"
1212: undo_step_cmd.small_icon = File.join(Constants::ICONS_DIR, "undo.PNG")
1213: undo_step_cmd.large_icon = File.join(Constants::ICONS_DIR, "undo.PNG")
1214: toolbar.add_item undo_step_cmd
1215:
1216: # Reset command
1217: reset_cmd = UI::Command.new("reset"){
1218: project = Shade.project
1219: execution = Shade.project.execution
1220: Sketchup.active_model.close_active
1221:
1222: execution.reset
1223: }
1224: reset_cmd.tooltip = "Reset"
1225: reset_cmd.small_icon = File.join(Constants::ICONS_DIR, "reset.PNG")
1226: reset_cmd.large_icon = File.join(Constants::ICONS_DIR, "reset.PNG")
1227: toolbar.add_item reset_cmd
1228:
1229: #Show labels command
1230: show_cmd = UI::Command.new("show_labels"){
1231: project = Shade.project
1232: execution = Shade.project.execution
1233: Sketchup.active_model.close_active
1234: execution.show_labels = true
1235: project.refresh()
1236: }
1237: show_cmd.tooltip = "Show labels"
1238: show_cmd.small_icon = File.join(Constants::ICONS_DIR, "show_labels.PNG")
1239: show_cmd.large_icon = File.join(Constants::ICONS_DIR, "show_labels.PNG")
1240: toolbar.add_item show_cmd
1241:
1242: #Hide labels command
1243: hide_cmd = UI::Command.new("hide_labels"){
1244: project = Shade.project
1245: execution = Shade.project.execution
1246: Sketchup.active_model.close_active
1247: execution.show_labels = false
1248: project.refresh()
1249: }
1250: hide_cmd.tooltip = "Hide labels"
1251: hide_cmd.small_icon = File.join(Constants::ICONS_DIR, "hide_labels.PNG")
1252: hide_cmd.large_icon = File.join(Constants::ICONS_DIR, "hide_labels.PNG")
1253: toolbar.add_item hide_cmd
1254:
1255: #Change size of labels command
1256: change_label_radius_cmd = UI::Command.new("change_label_radius"){
1257: prompts = ["New radius (between 0.1 and 0.9)"]
1258: default = [0.5]
1259: list = [""]
1260: input = UI.inputbox prompts, default, list, "New radius of labels"
1261: if input
1262: Shade.label_radius = input[0].to_f.m
1263: project = Shade.project
1264: execution = Shade.project.execution
1265: Sketchup.active_model.close_active
1266: project.refresh(true)
1267: end
1268: }
1269: change_label_radius_cmd.tooltip = "Change label radius"
1270: change_label_radius_cmd.small_icon = File.join(Constants::ICONS_DIR, "change_label_radius.PNG")
1271: change_label_radius_cmd.large_icon = File.join(Constants::ICONS_DIR, "change_label_radius.PNG")
1272: toolbar.add_item change_label_radius_cmd
1273:
1274: toolbar.add_separator
1275:
1276: # Save Design command
1277: save_design_cmd = UI::Command.new("save_design"){
1278: project = Shade.project
1279: execution = Shade.project.execution
1280: Sketchup.active_model.close_active
1281:
1282: saved = false
1283: while !saved
1284: path_to_save_to = UI.savepanel "Save Design", "", "design.txt"
1285: if (path_to_save_to)
1286: if ShadeUtils.get_extension(path_to_save_to) == "txt"
1287: begin
1288: execution.current_shape.save(path_to_save_to)
1289: saved = true
1290: rescue
1291: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)")
1292: end
1293: else
1294: UI.messagebox("Please save the design as a .txt file")
1295: end
1296: else
1297: saved = true
1298: end
1299: end
1300: }
1301: save_design_cmd.tooltip = "Save Design"
1302: save_design_cmd.small_icon = File.join(Constants::ICONS_DIR, "save_design.PNG")
1303: save_design_cmd.large_icon = File.join(Constants::ICONS_DIR, "save_design.PNG")
1304: toolbar.add_item save_design_cmd
1305:
1306: toolbar.add_separator
1307:
1308: toolbar.show
1309: end
Method that creates the toolbar for dealing with constraints and goals
# File lib/interfaces/guitools.rb, line 1312
1312: def create_guidance_toolbar
1313: toolbar = UI.toolbar Constants::GUIDANCE_TOOLBAR_NAME
1314:
1315: #Add constraint command
1316: add_constraint_cmd = UI::Command.new("add_constraint"){
1317: project = Shade.project
1318: execution = Shade.project.execution
1319: Sketchup.active_model.close_active
1320:
1321: prompts = ["Constraint: "]
1322: default = [Constants::DISTINCT_SHAPE_CONSTRAINT_NAME]
1323:
1324: array_list = ""
1325: Shade.constraint_class_names.each { |pair|
1326: array_list += "#{pair[1]}|"
1327: }
1328: list = [array_list[0..array_list.size-2]]
1329: input = UI.inputbox prompts, default, list, "Constraint to add"
1330: if input
1331: result = false
1332: if input[0] == Constants::AREA_CONSTRAINT_NAME
1333: prompts = ["Points: "]
1334: default = ["Default"]
1335: list = ["Default|From File"]
1336: input = UI.inputbox prompts, default, list, "Choose points"
1337: if input
1338: if input[0] == "Default"
1339: points = Constants::PTS_AREA.clone
1340: elsif input[0] == "From File"
1341: # TODO: make compatible with different OOSS (masks)
1342: chosen_area_path = UI.openpanel("Open area", "" ,"*.area")
1343: points = []
1344: File.open(chosen_area_path, 'r') do |f|
1345: while line = f.gets
1346: line_a = line.split
1347: point = Array.new
1348: point[0] = line_a[0].to_f.m
1349: point[1] = line_a[1].to_f.m
1350: point[2] = line_a[2].to_f.m
1351: points.push point
1352: end
1353: end
1354: end
1355: result = project.execution.add_constraint(AreaConstraint.new(points))
1356: end
1357: else
1358: i = 0
1359: found = false
1360: constraint_class = nil
1361: while ((i < Shade.constraint_class_names.size) && !found)
1362: if (Shade.constraint_class_names[i][1] == input[0])
1363: found = true
1364: constraint_class = Shade.constraint_class_names[i][0]
1365: end
1366: i+=1
1367: end
1368: if constraint_class
1369: result = project.execution.add_constraint(constraint_class.new)
1370: end
1371: end
1372: if !result
1373: UI.messagebox("The grammar already has the "+input[0]+" Constraint")
1374: end
1375: end
1376: }
1377: add_constraint_cmd.tooltip = "Add Constraint"
1378: add_constraint_cmd.small_icon = File.join(Constants::ICONS_DIR, "add_constraint.PNG")
1379: add_constraint_cmd.large_icon = File.join(Constants::ICONS_DIR, "add_constraint.PNG")
1380: toolbar.add_item add_constraint_cmd
1381:
1382: #Add custom constraint command
1383: add_custom_constraint_cmd = UI::Command.new("add_custom_constraint"){
1384:
1385: # Find and show our html file
1386: html_path = Sketchup.find_support_file "chooseName.html" ,Constants::HTML_DIR
1387: name_dialog = create_name_dialog("Constraint")
1388: name_dialog.set_file(html_path)
1389: name_dialog.show()
1390: }
1391: add_custom_constraint_cmd.tooltip = "Add Custom Constraint"
1392: add_custom_constraint_cmd.small_icon = File.join(Constants::ICONS_DIR, "add_custom_constraint.PNG")
1393: add_custom_constraint_cmd.large_icon = File.join(Constants::ICONS_DIR, "add_custom_constraint.PNG")
1394: toolbar.add_item add_custom_constraint_cmd
1395:
1396: #Remove constraint command
1397: remove_constraint_cmd = UI::Command.new("remove_constraint"){
1398: project = Shade.project
1399: execution = Shade.project.execution
1400: Sketchup.active_model.close_active
1401:
1402: prompts = ["Constraint: "]
1403: default = [Constants::DISTINCT_SHAPE_CONSTRAINT_NAME]
1404:
1405: array_list = ""
1406: Shade.constraint_class_names.each { |pair|
1407: array_list += "#{pair[1]}|"
1408: }
1409: list = [array_list[0..array_list.size-2]]
1410: input = UI.inputbox prompts, default, list, "Constraint to remove"
1411: if input
1412: result = project.execution.delete_constraint(input[0])
1413: if !result
1414: UI.messagebox("The grammar does not have the "+input[0]+" Constraint")
1415: end
1416: end
1417: #Here we do not have to reset the design, as the execution will be the same
1418: }
1419: remove_constraint_cmd.tooltip = "Remove Constraint"
1420: remove_constraint_cmd.small_icon = File.join(Constants::ICONS_DIR, "remove_constraint.PNG")
1421: remove_constraint_cmd.large_icon = File.join(Constants::ICONS_DIR, "remove_constraint.PNG")
1422: toolbar.add_item remove_constraint_cmd
1423:
1424: # Project Constraints command
1425: project_constraints_cmd = UI::Command.new("project_constraints"){
1426: project = Shade.project
1427: execution = Shade.project.execution
1428: constraints = ""
1429: execution.constraints.each{ |r|
1430: constraints = constraints + r.name + "\n"
1431: }
1432: UI.messagebox("Present Constraints on #{project.title}:\n "+constraints)
1433: }
1434: project_constraints_cmd.tooltip = "Project constraints"
1435: project_constraints_cmd.small_icon = File.join(Constants::ICONS_DIR, "project_constraints.PNG")
1436: project_constraints_cmd.large_icon = File.join(Constants::ICONS_DIR, "project_constraints.PNG")
1437: toolbar.add_item project_constraints_cmd
1438:
1439: toolbar.add_separator
1440:
1441: # Add goal command
1442: add_goal_command = UI::Command.new("add_goal"){
1443: project = Shade.project
1444: execution = Shade.project.execution
1445: Sketchup.active_model.close_active
1446:
1447: prompts = ["Goal: "]
1448: default = [Constants::NO_LABELS_GOAL_NAME]
1449:
1450: array_list = ""
1451: Shade.goal_class_names.each { |pair|
1452: array_list += "#{pair[1]}|"
1453: }
1454: list = [array_list[0..array_list.size-2]]
1455: input = UI.inputbox prompts, default, list, "Goal to add"
1456: if input
1457: result = false
1458: i = 0
1459: found = false
1460: goal_class = nil
1461: while ((i < Shade.goal_class_names.size) && !found)
1462: if (Shade.goal_class_names[i][1] == input[0])
1463: found = true
1464: goal_class = Shade.goal_class_names[i][0]
1465: end
1466: i+=1
1467: end
1468: if goal_class
1469: result = project.execution.add_goal(goal_class.new)
1470: end
1471: if !result
1472: UI.messagebox("The grammar already has the "+input[0]+" goal")
1473: end
1474: end
1475: }
1476: add_goal_command.tooltip = "Add Goal"
1477: add_goal_command.small_icon = File.join(Constants::ICONS_DIR, "add_goal.PNG")
1478: add_goal_command.large_icon = File.join(Constants::ICONS_DIR, "add_goal.PNG")
1479: toolbar.add_item add_goal_command
1480:
1481: #Add custom goal command
1482: add_custom_goal_cmd = UI::Command.new("add_custom_goal"){
1483: # Find and show our html file
1484: html_path = Sketchup.find_support_file "chooseName.html" ,Constants::HTML_DIR
1485: name_dialog = create_name_dialog("Goal")
1486: name_dialog.set_file(html_path)
1487: name_dialog.show()
1488: }
1489: add_custom_goal_cmd.tooltip = "Add Custom Goal"
1490: add_custom_goal_cmd.small_icon = File.join(Constants::ICONS_DIR, "add_custom_goal.PNG")
1491: add_custom_goal_cmd.large_icon = File.join(Constants::ICONS_DIR, "add_custom_goal.PNG")
1492: toolbar.add_item add_custom_goal_cmd
1493:
1494: # Remove goal command
1495: remove_goal_command = UI::Command.new("remove_goal"){
1496: project = Shade.project
1497: execution = Shade.project.execution
1498: Sketchup.active_model.close_active
1499:
1500: prompts = ["Goal: "]
1501: default = [Constants::NO_LABELS_GOAL_NAME]
1502:
1503: array_list = ""
1504: Shade.goal_class_names.each { |pair|
1505: array_list += "#{pair[1]}|"
1506: }
1507: list = [array_list[0..array_list.size-2]]
1508: input = UI.inputbox prompts, default, list, "Goal to remove"
1509: if input
1510: result = project.execution.delete_goal(input[0])
1511: if !result
1512: UI.messagebox("The grammar does not have the "+input[0]+" goal")
1513: end
1514: end
1515: }
1516: remove_goal_command.tooltip = "Remove Goal"
1517: remove_goal_command.small_icon = File.join(Constants::ICONS_DIR, "remove_goal.PNG")
1518: remove_goal_command.large_icon = File.join(Constants::ICONS_DIR, "remove_goal.PNG")
1519: toolbar.add_item remove_goal_command
1520:
1521: # Project Goals command
1522: project_goals_cmd = UI::Command.new("project_goals"){
1523: project = Shade.project
1524: execution = Shade.project.execution
1525: goals = ""
1526: execution.goals.each{ |g|
1527: goals = goals + g.name + "\n"
1528: }
1529: UI.messagebox("Present Goals on #{project.title}:\n "+goals)
1530: }
1531: project_goals_cmd.tooltip = "Project Goals"
1532: project_goals_cmd.small_icon = File.join(Constants::ICONS_DIR, "project_goals.PNG")
1533: project_goals_cmd.large_icon = File.join(Constants::ICONS_DIR, "project_goals.PNG")
1534: toolbar.add_item project_goals_cmd
1535:
1536: # Satisfy Goals command
1537: satisfy_goals_command = UI::Command.new("satisfy_goals"){
1538: project = Shade.project
1539: execution = Shade.project.execution
1540: if execution.goals_satisfied?
1541: UI.messagebox("The goals are satisfied")
1542: else
1543: UI.messagebox("The goals are not satisfied")
1544: end
1545: }
1546: satisfy_goals_command.tooltip = "Satisfy Goals?"
1547: satisfy_goals_command.small_icon = File.join(Constants::ICONS_DIR, "satisfy_goals.PNG")
1548: satisfy_goals_command.large_icon = File.join(Constants::ICONS_DIR, "satisfy_goals.PNG")
1549: toolbar.add_item satisfy_goals_command
1550:
1551: toolbar.add_separator
1552:
1553: # Create robot command
1554: create_robot_command = UI::Command.new("create_script"){
1555: Sketchup.active_model.close_active
1556: # Find and show our html file
1557: html_path = Sketchup.find_support_file "createRobot.html" , Constants::HTML_DIR
1558: robot_dialog = create_robot_dialog
1559: robot_dialog.set_file(html_path)
1560: robot_dialog.show()
1561: }
1562: create_robot_command.tooltip = "Create script"
1563: create_robot_command.small_icon = File.join(Constants::ICONS_DIR, "create_robot.PNG")
1564: create_robot_command.large_icon = File.join(Constants::ICONS_DIR, "create_robot.PNG")
1565: toolbar.add_item create_robot_command
1566:
1567: # Load robot command
1568: load_robot_command = UI::Command.new("load_script"){
1569: Sketchup.active_model.close_active
1570: chosen_robot_path = UI.openpanel("Open script", "" ,"*.txt")
1571: if chosen_robot_path
1572: robot = Robot.new
1573: robot.load(chosen_robot_path)
1574: Shade.robot = robot
1575: end
1576: }
1577: load_robot_command.tooltip = "Load script"
1578: load_robot_command.small_icon = File.join(Constants::ICONS_DIR, "load_robot.PNG")
1579: load_robot_command.large_icon = File.join(Constants::ICONS_DIR, "load_robot.PNG")
1580: toolbar.add_item load_robot_command
1581:
1582: # Execute robot command
1583: execute_robot_command = UI::Command.new("execute_script"){
1584: Sketchup.active_model.close_active
1585: if Shade.robot
1586: prompts = ["Number of designs"]
1587: default = ["1"]
1588: list = []
1589: input = UI.inputbox prompts, default, list, "Number of designs to generate"
1590:
1591: if input
1592: chosen_design_path = UI.savepanel("Save designs", "" ,"design.txt")
1593: if chosen_design_path
1594:
1595: Shade.robot.execute(input[0], File.dirname(chosen_design_path))
1596: Shade.project.refresh(true)
1597: UI.beep
1598: end
1599: end
1600: else
1601: UI.messagebox("No script has been loaded")
1602: end
1603: }
1604: execute_robot_command.tooltip = "Execute script"
1605: execute_robot_command.small_icon = File.join(Constants::ICONS_DIR, "execute_robot.PNG")
1606: execute_robot_command.large_icon = File.join(Constants::ICONS_DIR, "execute_robot.PNG")
1607: toolbar.add_item execute_robot_command
1608:
1609: toolbar.show
1610:
1611: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
| predicate_type | “Constraint” or “Goal” |
Method that creates the dialog for choosing the name of a custom constraint or goal
# File lib/interfaces/custom.rb, line 13
13: def create_name_dialog(predicate_type)
14:
15: name = nil
16: # Create the WebDialog instance for choosing the name
17: name_dialog = UI::WebDialog.new("Choose #{predicate_type} name", true, "Choose #{predicate_type} name", 250, 150, 150, 150, true)
18:
19: # Attach an action callback
20: name_dialog.add_action_callback("get_name") do |web_dialog, name|
21:
22: #Obtain the class name
23: class_name = name.gsub(" ", "_")
24: class_name[0] = class_name[0].chr.to_s.upcase
25:
26: #If class_name is not used...
27: if !Object.const_defined?(class_name)
28:
29: name_dialog.close
30: # Find and show our html file
31: html_path = Sketchup.find_support_file "chooseInterfaceType.html" , Constants::HTML_DIR
32: choose_interface_dialog = create_choose_interface_dialog(predicate_type, class_name)
33: choose_interface_dialog.set_file(html_path)
34: choose_interface_dialog.show()
35: else
36: UI.messagebox("The name is already in use")
37: end
38: end
39:
40: return name_dialog
41: end
| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
Method that creates the dialog for configuring a design script that will be able to execute a number of projects in a sequential manner
# File lib/interfaces/custom.rb, line 1024
1024: def create_robot_dialog
1025: gui_dialog_robot = UI::WebDialog.new("Create new design script", true, "Create new design script", 500, 300, 150, 150, true)
1026:
1027: Shade.robot = Robot.new
1028:
1029: # Attach an action callback for saving the script
1030: gui_dialog_robot.add_action_callback("save_robot") do |web_dialog, kk|
1031:
1032: if Shade.robot.project_paths.size > 0
1033:
1034: path_to_save_to = UI.savepanel "Save Script", "", "script.txt"
1035: if path_to_save_to
1036: Shade.robot.save(path_to_save_to)
1037: gui_dialog_robot.close
1038: end
1039:
1040: else
1041: UI.messagebox("There are no projects added")
1042: end
1043:
1044: end
1045:
1046: # Attach an action callback for adding a project to the script
1047: gui_dialog_robot.add_action_callback("add_project") do |web_dialog, kk|
1048:
1049: project_path = UI.openpanel("Open project", "" ,"*.prj")
1050: prompts = ["Execution mode"]
1051: default = ["Goals"]
1052: list = ["Goals|Number of rules"]
1053: input = UI.inputbox prompts, default, list, "Execution mode"
1054:
1055: if input
1056: execution_mode = input[0]
1057: mode_string = input[0].to_s
1058: ok = true
1059: if !(input[0] == "Goals")
1060: prompts = ["Number of rules"]
1061: default = ["1"]
1062: list = []
1063: n_input = UI.inputbox prompts, default, list, "Number of rules"
1064:
1065: if n_input
1066: mode_string = "#{n_input[0]} rules"
1067: execution_mode = n_input[0]
1068:
1069: else
1070: ok = false
1071: end
1072: end
1073: if ok
1074: Shade.robot.project_paths.push project_path
1075: Shade.robot.execution_modes.push execution_mode
1076: project_info_string = "#{ShadeUtils.get_title_from_path(project_path)}:#{mode_string}"
1077: js_command = "writeProjectInfo(\"#{project_info_string}\")"
1078: web_dialog.execute_script(js_command)
1079: end
1080: end
1081:
1082: end
1083:
1084: return gui_dialog_robot
1085: end
Method that creates the toolbar for saving and loading projects, grammars and shapes, as well as editing rules
# File lib/interfaces/guitools.rb, line 237
237: def create_static_toolbar()
238:
239: toolbar = UI.toolbar Constants::STATIC_TOOLBAR_NAME
240:
241: #New Project command
242: newp_cmd = UI::Command.new("new_project"){
243: project = Shade.project
244: execution = Shade.project.execution
245: Sketchup.active_model.close_active
246: execution.reset
247:
248: #Before creating a new project, we save the current one if necessary
249: if !project.saved
250: input = UI.messagebox("Save current project?", MB_YESNOCANCEL)
251: if input == 6
252: if project.path
253: project.save(project.path, true)
254: else
255: saved = false
256: while !saved
257: path_to_save_to = UI.savepanel "Save Project", "", "project.prj"
258: if path_to_save_to
259: if ShadeUtils.get_extension(path_to_save_to) == "prj"
260: begin
261: project.save(path_to_save_to, true)
262: saved = true
263: rescue
264: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)")
265: end
266: else
267: UI.messagebox("Please save the project as a .prj file")
268: end
269: else
270: saved = true
271: end
272: end
273: end
274: end
275: end
276: ShadeUtils.create_default_new_project()
277: }
278: newp_cmd.tooltip = "New project"
279: newp_cmd.small_icon = File.join(Constants::ICONS_DIR, "new_project.PNG")
280: newp_cmd.large_icon = File.join(Constants::ICONS_DIR, "new_project.PNG")
281: toolbar.add_item newp_cmd
282:
283: #Open Project command
284: openp_cmd = UI::Command.new("open_project"){
285: project = Shade.project
286: execution = Shade.project.execution
287: Sketchup.active_model.close_active
288: #execution.reset
289:
290: if !project.saved
291: input = UI.messagebox("Save current project?", MB_YESNOCANCEL)
292: if input == 6
293: if project.path
294: project.save(project.path, true)
295: else
296: saved = false
297: while !saved
298: path_to_save_to = UI.savepanel "Save Project", "", "project.prj"
299: if path_to_save_to
300: if ShadeUtils.get_extension(path_to_save_to) == "prj"
301: begin
302: project.save(path_to_save_to, true)
303: saved = true
304: rescue
305: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)")
306: end
307: else
308: UI.messagebox("Please save the project as a .prj file")
309: end
310: else
311: saved = true
312: end
313: end
314: end
315: end
316: end
317:
318: opened = false
319: while !opened
320: chosen_project_path = UI.openpanel("Open project", "" ,"*.prj")
321: if chosen_project_path
322: if ShadeUtils.get_extension(chosen_project_path) == "prj"
323: begin
324: project.load(chosen_project_path)
325: project.saved = true
326: project.refresh
327: opened = true
328: rescue
329: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)")
330: rescue LoadError => e
331: UI.messagebox(e.message)
332: end
333: else
334: UI.messagebox("Please choose a .prj file")
335: end
336: else
337: opened = true
338: end
339: end
340:
341: }
342: openp_cmd.tooltip = "Open project"
343: openp_cmd.small_icon = File.join(Constants::ICONS_DIR, "open_project.PNG")
344: openp_cmd.large_icon = File.join(Constants::ICONS_DIR, "open_project.PNG")
345: toolbar.add_item openp_cmd
346:
347: #Save Project command
348: savep_cmd = UI::Command.new("save_project"){
349: project = Shade.project
350: execution = Shade.project.execution
351: Sketchup.active_model.close_active
352:
353: if project.path
354: project.save(project.path, true)
355: else
356: saved = false
357: while !saved
358: path_to_save_to = UI.savepanel "Save Project", "", "project.prj"
359: if path_to_save_to
360: if ShadeUtils.get_extension(path_to_save_to) == "prj"
361: begin
362: project.save(path_to_save_to, true)
363: saved = true
364: rescue
365: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)")
366: end
367: else
368: UI.messagebox("Please save the project as a .prj file")
369: end
370: else
371: saved = true
372: end
373: end
374: end
375: }
376: savep_cmd.tooltip = "Save project"
377: savep_cmd.small_icon = File.join(Constants::ICONS_DIR, "save_project.PNG")
378: savep_cmd.large_icon = File.join(Constants::ICONS_DIR, "save_project.PNG")
379: toolbar.add_item savep_cmd
380:
381: #Save Project as command
382: savepas_cmd = UI::Command.new("save_project_as"){
383: project = Shade.project
384: execution = Shade.project.execution
385: Sketchup.active_model.close_active
386:
387: saved = false
388: while !saved
389: path_to_save_to = UI.savepanel "Save Project", "", "project.prj"
390: if path_to_save_to
391: if ShadeUtils.get_extension(path_to_save_to) == "prj"
392: begin
393: project.save(path_to_save_to, true)
394: saved = true
395: rescue
396: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)")
397: end
398: else
399: UI.messagebox("Please save the project as a .prj file")
400: end
401: else
402: saved = true
403: end
404: end
405:
406: }
407: savepas_cmd.tooltip = "Save project as"
408: savepas_cmd.small_icon = File.join(Constants::ICONS_DIR, "save_project_as.PNG")
409: savepas_cmd.large_icon = File.join(Constants::ICONS_DIR, "save_project_as.PNG")
410: toolbar.add_item savepas_cmd
411:
412: toolbar.add_separator
413:
414: #New Grammar command
415: newg_cmd = UI::Command.new("new_grammar"){
416: project = Shade.project
417: execution = Shade.project.execution
418: Sketchup.active_model.close_active
419: execution.reset
420:
421: if !execution.grammar.saved
422: input = UI.messagebox("Save current grammar?", MB_YESNOCANCEL)
423: if input == 6
424: saved = false
425: while !saved
426: path_to_save_to = UI.savepanel "Save Grammar", "", "grammar.gr2"
427: if path_to_save_to
428: if ShadeUtils.get_extension(path_to_save_to) == "gr2"
429: begin
430: execution.grammar.save(path_to_save_to, true)
431: saved = true
432: rescue
433: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)")
434: end
435: else
436: UI.messagebox("Please save the grammar as a .gr2 file")
437: end
438: else
439: saved = true
440: end
441: end
442: end
443: end
444: ShadeUtils.create_default_new_grammar()
445: project.saved = false
446: project.refresh
447: }
448: newg_cmd.tooltip = "New grammar"
449: newg_cmd.small_icon = File.join(Constants::ICONS_DIR, "new_grammar.PNG")
450: newg_cmd.large_icon = File.join(Constants::ICONS_DIR, "new_grammar.PNG")
451: toolbar.add_item newg_cmd
452:
453: #Open Grammar command
454: openg_cmd = UI::Command.new("open_grammar"){
455: project = Shade.project
456: execution = Shade.project.execution
457: Sketchup.active_model.close_active
458: execution.reset
459:
460: if !execution.grammar.saved
461: input = UI.messagebox("Save current grammar?", MB_YESNOCANCEL)
462: if input == 6
463: saved = false
464: while !saved
465: path_to_save_to = UI.savepanel "Save Grammar", "", "grammar.gr2"
466: if path_to_save_to
467: if ShadeUtils.get_extension(path_to_save_to) == "gr2"
468: begin
469: execution.grammar.save(path_to_save_to, true)
470: saved = true
471: rescue
472: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)")
473: end
474: else
475: UI.messagebox("Please save the grammar as a .gr2 file")
476: end
477: else
478: saved = true
479: end
480: end
481: end
482: end
483:
484: opened = false
485: while !opened
486: chosen_grammar_path = UI.openpanel("Open grammar", "" ,"*.gr2")
487: if chosen_grammar_path
488: if ShadeUtils.get_extension(chosen_grammar_path) == "gr2"
489: begin
490: execution.grammar.load(chosen_grammar_path)
491: opened = true
492: project.saved = false
493: project.refresh
494: rescue LoadError => e
495: UI.messagebox(e.message)
496: rescue
497: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)")
498: end
499: else
500: UI.messagebox("Please choose a .gr2 file")
501: end
502: else
503: opened = true
504: end
505: end
506: }
507: openg_cmd.tooltip = "Open grammar"
508: openg_cmd.small_icon = File.join(Constants::ICONS_DIR, "open_grammar.PNG")
509: openg_cmd.large_icon = File.join(Constants::ICONS_DIR, "open_grammar.PNG")
510: toolbar.add_item openg_cmd
511:
512: #Save Grammar As command
513: savegas_cmd = UI::Command.new("save_grammar_as"){
514: project = Shade.project
515: execution = Shade.project.execution
516: Sketchup.active_model.close_active
517: saved = false
518: while !saved
519: path_to_save_to = UI.savepanel "Save Grammar", "", "grammar.gr2"
520: if path_to_save_to
521: if ShadeUtils.get_extension(path_to_save_to) == "gr2"
522: begin
523: execution.grammar.save(path_to_save_to, true)
524: saved = true
525: rescue
526: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)")
527: end
528: else
529: UI.messagebox("Please save the grammar as a .gr2 file")
530: end
531: else
532: saved = true
533: end
534: end
535: }
536: savegas_cmd.tooltip = "Save grammar as"
537: savegas_cmd.small_icon = File.join(Constants::ICONS_DIR, "save_grammar_as.PNG")
538: savegas_cmd.large_icon = File.join(Constants::ICONS_DIR, "save_grammar_as.PNG")
539: toolbar.add_item savegas_cmd
540:
541: toolbar.add_separator
542:
543: #Add Rule command
544: add_rule_cmd = UI::Command.new("add_rule"){
545: project = Shade.project
546: execution = Shade.project.execution
547: Sketchup.active_model.close_active
548:
549: size = execution.grammar.rules.size
550:
551: #Create the default shapes
552: left = ShadeUtils.create_default_left_shape
553: right = ShadeUtils.create_default_right_shape
554:
555: #Obtain new rule id
556: last_id = execution.grammar.rules[size-1].rule_id
557:
558: #Create new rule
559: new_rule = ShadeUtils.paint_rule(last_id+1, left, right)
560: execution.grammar.add_rule(new_rule)
561: project.refresh
562: }
563: add_rule_cmd.tooltip = "Add rule"
564: add_rule_cmd.small_icon = File.join(Constants::ICONS_DIR, "add_rule.PNG")
565: add_rule_cmd.large_icon = File.join(Constants::ICONS_DIR, "add_rule.PNG")
566: toolbar.add_item add_rule_cmd
567:
568: #Delete Rule command
569: delete_rule_cmd = UI::Command.new("delete_rule"){
570: project = Shade.project
571: execution = Shade.project.execution
572: Sketchup.active_model.close_active
573:
574: if execution.grammar.rules.size > 1
575: prompts = ["Rule to delete: "]
576: default = ["1"]
577: rule_list = ShadeUtils.create_rule_list()
578: list = [rule_list]
579: input = UI.inputbox prompts, default, list, "Delete Rule"
580: if input
581: chosen_rule_idx = input[0].to_i-1
582:
583: if ((chosen_rule_idx == 0) && (!execution.file_axiom))
584: previous_rule = execution.grammar.rules[1]
585: # Add new axiom
586: new_axiom = LabelledShape.new(Array.new, Array.new)
587: Sketchup.active_model.layers.each { |layer|
588: new_axiom.p[layer.name] = previous_rule.left.p[layer.name].clone
589: new_axiom.s[layer.name] = previous_rule.left.s[layer.name].clone
590: }
591: execution.grammar.axiom = new_axiom
592:
593: execution.reset
594: end
595: execution.grammar.remove_rule(chosen_rule_idx)
596: # Transform the position of the rules from chosen_rule_idx
597: idx = chosen_rule_idx
598:
599: while idx < execution.grammar.rules.size
600:
601: current_rule = execution.grammar.rules[idx]
602:
603: current_rule.left.layout_transformation = current_rule.left.layout_transformation * Constants::DESCEND_T.inverse
604: current_rule.right.layout_transformation = current_rule.right.layout_transformation * Constants::DESCEND_T.inverse
605:
606: current_rule.left.changed = true
607: current_rule.right.changed = true
608:
609: Sketchup.active_model.layers.each { |layer|
610: current_rule.arrow_group[layer.name].locked = false
611: current_rule.arrow_group[layer.name].transform! Constants::DESCEND_T.inverse
612: current_rule.arrow_group[layer.name].locked = true
613:
614: current_rule.line_group[layer.name].locked = false
615: current_rule.line_group[layer.name].transform! Constants::DESCEND_T.inverse
616: current_rule.line_group[layer.name].locked = true
617:
618: current_rule.group_origin_left[layer.name].locked = false
619: current_rule.group_origin_left[layer.name].transform! Constants::DESCEND_T.inverse
620: current_rule.group_origin_left[layer.name].locked = true
621:
622: current_rule.group_origin_right[layer.name].locked = false
623: current_rule.group_origin_right[layer.name].transform! Constants::DESCEND_T.inverse
624: current_rule.group_origin_right[layer.name].locked = true
625: }
626:
627: idx += 1
628: end
629: execution.reset
630: project.refresh
631: end
632: else
633: UI.messagebox("You cannot delete all rules")
634: end
635: }
636: delete_rule_cmd.tooltip = "Delete rule"
637: delete_rule_cmd.small_icon = File.join(Constants::ICONS_DIR, "delete_rule.PNG")
638: delete_rule_cmd.large_icon = File.join(Constants::ICONS_DIR, "delete_rule.PNG")
639: toolbar.add_item delete_rule_cmd
640:
641: #Copy Rule command
642: copy_rule_cmd = UI::Command.new("copy_rule"){
643: project = Shade.project
644: execution = Shade.project.execution
645: Sketchup.active_model.close_active
646:
647: prompts = ["Rule to copy: "]
648: default = ["1"]
649:
650: rule_list = ShadeUtils.create_rule_list()
651: list = [rule_list]
652: input = UI.inputbox prompts, default, list, "Rule to copy"
653: if input
654: n_rule = input[0].to_i-1
655: if n_rule < execution.grammar.rules.size
656: rule = execution.grammar.rules[n_rule]
657: size = execution.grammar.rules.size
658:
659: # Obtain shape transformations
660: t_left = rule.left.shape_transformation
661: t_right = rule.right.shape_transformation
662:
663: # Obtain the new shapes
664: left = rule.left.clone
665: right = rule.right.clone
666:
667: #Paint the rule
668: last_id = execution.grammar.rules[size-1].rule_id
669:
670: new_rule = ShadeUtils.paint_rule(last_id+1, left, right)
671:
672: #Transform the shapes
673: left.shape_transformation = t_left
674: right.shape_transformation = t_right
675:
676: execution.grammar.add_rule(new_rule)
677: project.refresh
678: else
679: UI.messagebox("Rule " + (n_rule+1).to_s + " doesn't exist")
680: end
681: end
682: }
683: copy_rule_cmd.tooltip = "Copy rule"
684: copy_rule_cmd.small_icon = File.join(Constants::ICONS_DIR, "copy_rule.PNG")
685: copy_rule_cmd.large_icon = File.join(Constants::ICONS_DIR, "copy_rule.PNG")
686: toolbar.add_item copy_rule_cmd
687:
688: #Add label command
689: add_label_cmd = UI::Command.new("add_label"){
690: project = Shade.project
691: execution = Shade.project.execution
692: Sketchup.active_model.close_active
693:
694: prompts = ["Rule ID ", "Rule part ", "Color "]
695: default = ["1", Constants::LEFT, "Red"]
696: rule_list = ShadeUtils.create_rule_list()
697: list = [rule_list, "#{Constants::LEFT}|#{Constants::RIGHT}", "Red|Green|Blue|Yellow|White|Black"]
698: input = UI.inputbox prompts, default, list, "Add label to shape:"
699: if input
700: rule_idx = input[0].to_i - 1
701: rule = execution.grammar.rules[rule_idx]
702: if input[1] == Constants::LEFT
703: shape = rule.left
704: else
705: shape = rule.right
706: end
707: color = input[2]
708: add_label_tool = AddLabelTool.new(shape, color)
709: Sketchup.active_model.select_tool add_label_tool
710: end
711: }
712: add_label_cmd.tooltip = "Add label to shape"
713: add_label_cmd.small_icon = File.join(Constants::ICONS_DIR, "add_label.PNG")
714: add_label_cmd.large_icon = File.join(Constants::ICONS_DIR, "add_label.PNG")
715: toolbar.add_item add_label_cmd
716:
717: # Copy shape command
718: copy_shape_cmd = UI::Command.new("copy_shape"){
719: project = Shade.project
720: execution = Shade.project.execution
721: Sketchup.active_model.close_active
722:
723: prompts = ["Origin Rule ID ", "Origin Rule part ", "Destiny Rule ID ", "Destiny rule part "]
724: default = ["1", Constants::LEFT, "1", Constants::RIGHT]
725: rule_list = ShadeUtils.create_rule_list()
726: list = [rule_list, "#{Constants::LEFT}|#{Constants::RIGHT}", rule_list, "#{Constants::LEFT}|#{Constants::RIGHT}"]
727: input = UI.inputbox prompts, default, list, "Copy shape:"
728: if input
729: origin_rule_idx = input[0].to_i - 1
730: origin_rule_part = input[1]
731: destiny_rule_idx = input[2].to_i - 1
732: destiny_rule_part = input[3]
733: ShadeUtils.copy_shape(origin_rule_idx, origin_rule_part, destiny_rule_idx, destiny_rule_part)
734: project.refresh
735: end
736: }
737: copy_shape_cmd.tooltip = "Copy shape"
738: copy_shape_cmd.small_icon = File.join(Constants::ICONS_DIR, "copy_shape.PNG")
739: copy_shape_cmd.large_icon = File.join(Constants::ICONS_DIR, "copy_shape.PNG")
740: toolbar.add_item copy_shape_cmd
741:
742: # Add shape box command
743: add_shape_box_command = UI::Command.new("add_shape_box"){
744: Sketchup.active_model.close_active
745: prompts = ["Rule ID ", "Rule part "]
746: default = ["1", "Left"]
747: rule_list = ShadeUtils.create_rule_list()
748: list = [rule_list, "Left|Right"]
749: input = UI.inputbox prompts, default, list, "Choose shape:"
750:
751: if input
752: rule_idx = input[0].to_i - 1
753: # Transform the layout transformation of the shapes
754: t = Geom::Transformation.new
755: rule_idx.times do
756: t = Constants::DESCEND_T * t
757: end
758:
759: rule = Shade.project.execution.grammar.rules[rule_idx]
760: if input[1] == "Left"
761: t = Constants::LEFT_T * t
762: rule.alpha.erase
763: rule.alpha = ShadeUtils.create_default_left_shape
764: rule.alpha.layout_transformation = t
765: rule.alpha.paint
766: if ((rule_idx == 0) and (!Shade.project.execution.file_axiom))
767: new_axiom = ShadeUtils.create_default_axiom
768: Shade.project.execution.grammar.axiom = new_axiom
769: Shade.project.execution.reset
770: end
771: else
772: t = Constants::RIGHT_T * t
773: rule.beta.erase
774: rule.beta= ShadeUtils.create_default_right_shape
775: rule.beta.layout_transformation = t
776: rule.beta.paint
777: end
778: end
779: }
780: add_shape_box_command.tooltip = "Add Shape Box"
781: add_shape_box_command.small_icon = File.join(Constants::ICONS_DIR, "create_shape_box.PNG")
782: add_shape_box_command.large_icon = File.join(Constants::ICONS_DIR, "create_shape_box.PNG")
783: toolbar.add_item add_shape_box_command
784:
785: toolbar.add_separator
786:
787: # Load shape command
788: load_shape_cmd = UI::Command.new("load_shape"){
789: Sketchup.active_model.close_active
790: prompts = ["Rule ID ", "Rule part "]
791: default = ["1", "Left"]
792: rule_list = ShadeUtils.create_rule_list()
793: list = [rule_list, "Left|Right"]
794: input = UI.inputbox prompts, default, list, "Choose shape:"
795: if input
796: rule_idx = input[0].to_i - 1
797: rule = Shade.project.execution.grammar.rules[rule_idx]
798: if input[1] == "Left"
799: shape = rule.left
800: else
801: shape = rule.right
802: end
803: opened = false
804: while !opened
805: load_shape_path = UI.openpanel "Load Shape", "", "*.txt"
806: if load_shape_path
807: if ShadeUtils.get_extension(load_shape_path) == "txt"
808: begin
809: shape.load(load_shape_path)
810: opened = true
811: if ((rule_idx == 0) && (input[1] == "Left") && (!Shade.project.execution.file_axiom))
812: # Add new axiom
813: new_axiom = LabelledShape.new(Array.new, Array.new)
814: Sketchup.active_model.layers.each { |layer|
815: new_axiom.p = shape.p.clone
816: new_axiom.s = shape.s.clone
817: }
818: Shade.project.execution.grammar.axiom = new_axiom
819: Shade.project.execution.reset
820: end
821: rescue LoadError => e
822: UI.messagebox(e.message)
823: rescue
824: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)")
825: end
826: else
827: UI.messagebox("Please choose a .txt file")
828: end
829: else
830: opened = true
831: end
832: end
833: end
834: }
835: load_shape_cmd.tooltip = "Load shape"
836: load_shape_cmd.small_icon = File.join(Constants::ICONS_DIR, "load_shape.PNG")
837: load_shape_cmd.large_icon = File.join(Constants::ICONS_DIR, "load_shape.PNG")
838: toolbar.add_item load_shape_cmd
839:
840: # Save shape command
841: save_shape_cmd = UI::Command.new("save_shape"){
842: Sketchup.active_model.close_active
843: prompts = ["Rule ID ", "Rule part "]
844: default = ["1", "Left"]
845: rule_list = ShadeUtils.create_rule_list()
846: list = [rule_list, "Left|Right"]
847: input = UI.inputbox prompts, default, list, "Choose shape:"
848: if input
849: rule_idx = input[0].to_i - 1
850: rule = Shade.project.execution.grammar.rules[rule_idx]
851: if input[1] == "Left"
852: shape = rule.left
853: else
854: shape = rule.right
855: end
856: saved = false
857: while !saved
858: save_shape_path = UI.savepanel "Save Shape", "", "shape.txt"
859: if save_shape_path
860: if ShadeUtils.get_extension(save_shape_path) == "txt"
861: begin
862: shape.save(save_shape_path)
863: saved = true
864: rescue
865: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)")
866: end
867: else
868: UI.messagebox("Please save the shape as a .txt file")
869: end
870: else
871: saved = true
872: end
873: end
874: end
875: }
876: save_shape_cmd.tooltip = "Save shape"
877: save_shape_cmd.small_icon = File.join(Constants::ICONS_DIR, "save_shape.PNG")
878: save_shape_cmd.large_icon = File.join(Constants::ICONS_DIR, "save_shape.PNG")
879: toolbar.add_item save_shape_cmd
880:
881: toolbar.add_separator
882:
883: # About command
884: about_cmd = UI::Command.new("about"){
885: UI.messagebox("ShaDe v#{Constants::VERSION}\nAll rights reserved\nFor research use only \n(c) Manuela Ruiz Montiel and Universidad de Malaga")
886: }
887: about_cmd.tooltip = "About"
888: about_cmd.small_icon = File.join(Constants::ICONS_DIR, "about.PNG")
889: about_cmd.large_icon = File.join(Constants::ICONS_DIR, "about.PNG")
890: toolbar.add_item about_cmd
891:
892: toolbar.show
893: end
Deletes all the files inside temp folder
# File lib/interfaces/guitools.rb, line 227
227: def delete_temp_files()
228: dir = Dir.new("#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}")
229: dir.each { |file_name|
230: if file_name == '.' or file_name == '..' then next
231: else File.delete("#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/#{file_name}")
232: end
233: }
234: end
Loads the temp files
# File lib/interfaces/guitools.rb, line 210
210: def load_temp_files()
211: execution = Shade.project.execution
212:
213: #STEP 1: Load execution history
214: history_directory = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}"
215: history_directory.gsub!("/", "\\")
216: execution.load_execution_history(history_directory)
217:
218: #STEP 1: Load current shape
219: current_shape_path = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/current_shape.txt"
220: current_shape_path.gsub!("/", "\\")
221: execution.current_shape.load(current_shape_path)
222: execution.current_shape.refresh
223: execution.current_shape.create_pi
224: end
Saves the project, the current shape and the execution history
# File lib/interfaces/guitools.rb, line 190
190: def save_temp_files()
191: project = Shade.project
192:
193: #STEP 1: Save project
194: project_path = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/project.txt"
195: project_path.gsub!("/", "\\")
196: project.save(project_path, true)
197:
198: #STEP 2: Save current shape
199: current_shape_path = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/current_shape.txt"
200: current_shape_path.gsub!("/", "\\")
201: project.execution.current_shape.save(current_shape_path)
202:
203: #STEP 2: Save execution history
204: history_directory = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}"
205: history_directory.gsub!("/", "\\")
206: project.execution.save_execution_history(history_directory)
207: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.